<template>
  <div
    v-if="callInfoContextValue.callStatus !== CallStatus.IDLE"
    :style="[{ visibility: floatWindowContextValue.isFloatWindow ? 'hidden' : '' }]"
    id="tuicallkit-id"
    :class="[bodyStyle, miniMizedDeskStyle, mobileVideoStyle, mobileAudioStyle]"
  >
    <SingleCall v-if="!callInfoContextValue.isGroupCall" class="singCall"></SingleCall>
    <GroupCall v-else class="singCall"></GroupCall>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, reactive, onUnmounted, toRefs, watchEffect, provide } from '../adapter-vue'
import SingleCall from './components/SingleCall/SingleCall.vue'
import GroupCall from './components/GroupCall/GroupCall.vue'
import { PermitTip } from './components/common/PermitTip/PermitTip'
import { Toast } from './components/common/Toast'
import {
  TUIGlobal,
  TUIStore,
  StoreName,
  TUICallKitServer,
  NAME,
  CallStatus,
  CallMediaType
} from '../TUICallService/index'
import {
  CallInfoContextKey,
  CallerUserInfoContextKey,
  UserInfoExcludeVolumeContextKey,
  FloatWindowContextKey,
  TCallerUserInfoValue,
  TFloatWindowContextValue
} from './context'

const isMobile = !TUIGlobal.isPC
const bodyStyle = isMobile ? 'TUICallKit-mobile transition-animation' : 'TUICallKit-desktop'
const miniMizedDeskStyle = ref('')
const mobileAudioStyle = ref('')
const mobileVideoStyle = ref('')
const isShowFloatWindow = ref(false)
const props = withDefaults(
  defineProps<{
    beforeCalling?: (...args: any[]) => void
    afterCalling?: (...args: any[]) => void
    onMinimized?: (...args: any[]) => void
    onMessageSentByMe?: (...args: any[]) => void
    kickedOut?: (...args: any[]) => void
    statusChanged?: (...args: any[]) => void
    allowedMinimized?: boolean
    allowedFullScreen?: boolean
    videoDisplayMode?: string
    videoResolution?: string
  }>(),
  {
    allowedMinimized: false,
    allowedFullScreen: true,
    videoDisplayMode: 'cover',
    videoResolution: '480p'
  }
)

const callStatus = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS))
const callRole = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE))
const callType = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE))
const isGroupCall = ref(TUIStore.getData(StoreName.CALL, NAME.IS_GROUP))
const isEarPhone = ref(TUIStore.getData(StoreName.CALL, NAME.IS_EAR_PHONE))
const focusElement = ref(null)
const localUserInfoExcludeVolume = ref(
  TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN)
)
const remoteUserListExcludeVolume = ref(
  TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST)
)
const callerUserInfo = ref(TUIStore.getData(StoreName.CALL, NAME.CALLER_USER_INFO))
const isFloatWindow = ref(TUIStore.getData(StoreName.CALL, NAME.IS_MINIMIZED))
const callInfoContextValue = reactive({
  callStatus,
  callRole,
  callType,
  isGroupCall,
  isEarPhone,
  focusElement,
  allowedFullScreen: props.allowedFullScreen
})
const callerUserInfoValue: TCallerUserInfoValue = reactive({ callerUserInfo })
const userInfoExcludeVolumeContextValue = reactive({
  localUserInfoExcludeVolume,
  remoteUserListExcludeVolume
})
const floatWindowContextValue: TFloatWindowContextValue = reactive({
  isFloatWindow
})

const {
  beforeCalling,
  afterCalling,
  onMinimized,
  onMessageSentByMe,
  videoDisplayMode,
  videoResolution,
  kickedOut,
  statusChanged,
  allowedMinimized
} = toRefs(props)

const handleCallStatusChange = (value) => {
  callInfoContextValue.callStatus = value
  console.log('value123132', value)
}
const handleIsGroupChange = (value) => {
  callInfoContextValue.isGroupCall = value
}
const handleToastInfoChange = (value) => {
  if (value.text) {
    showToast(value.text, value.type || 'info')
  }
}

const handleCallMediaTypeChange = (value) => {
  callInfoContextValue.callType = value
  if (isMobile && isShowFloatWindow.value) {
    mobileVideoStyle.value = 'miniMized-mobile-audio'
    mobileAudioStyle.value = ''
  }

  if (isMobile && !isShowFloatWindow.value) {
    mobileAudioStyle.value = 'mobile-audio'
  }
}

const handleIsMinimizedChange = (value) => {
  floatWindowContextValue.isFloatWindow = value
  // 开启悬浮窗
  if (value) {
    if (!isMobile) {
      miniMizedDeskStyle.value = 'miniMized'
    } else {
      if (callInfoContextValue.callType === CallMediaType.AUDIO) {
        mobileAudioStyle.value = 'miniMized-mobile-audio'
      } else {
        mobileVideoStyle.value = 'miniMized-mobile-video'
      }
    }
  } else {
    // 关闭悬浮窗
    mobileAudioStyle.value = 'mobile-audio'
    miniMizedDeskStyle.value = ''
    mobileVideoStyle.value = ''
  }
}

const handlePermissionErrorTipChange = (data) => {
  if (data && TUIGlobal.isPC) {
    try {
      PermitTip.show()
    } catch (error) {
      console.debug(error)
    }
  }
}
const handleCallRoleChange = (value) => {
  callInfoContextValue.callRole = value
}
const handleLocalUserInfoChange = (value) => {
  userInfoExcludeVolumeContextValue.localUserInfoExcludeVolume = value
}
const handleRemoteUserInfoListChange = (value) => {
  userInfoExcludeVolumeContextValue.remoteUserListExcludeVolume = value
}
const handleCallerUserInfoChange = (value) => {
  callerUserInfoValue.callerUserInfo = value
}
const handEarPhoneChange = (value) => {
  callInfoContextValue.isEarPhone = value
}

watchEffect(() => {
  TUICallKitServer.setCallback({
    beforeCalling: beforeCalling && beforeCalling.value,
    afterCalling: afterCalling && afterCalling.value,
    onMinimized: onMinimized && onMinimized.value,
    onMessageSentByMe: onMessageSentByMe && onMessageSentByMe.value,
    kickedOut: kickedOut && kickedOut.value,
    statusChanged: statusChanged && statusChanged.value
  })
})

const watchOptions = {
  [NAME.CALL_STATUS]: handleCallStatusChange,
  [NAME.IS_GROUP]: handleIsGroupChange,
  [NAME.TOAST_INFO]: handleToastInfoChange,
  [NAME.CALL_MEDIA_TYPE]: handleCallMediaTypeChange,
  [NAME.SHOW_PERMISSION_TIP]: handlePermissionErrorTipChange,
  [NAME.CALL_ROLE]: handleCallRoleChange,
  [NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN]: handleLocalUserInfoChange,
  [NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: handleRemoteUserInfoListChange,
  [NAME.CALLER_USER_INFO]: handleCallerUserInfoChange,
  [NAME.IS_EAR_PHONE]: handEarPhoneChange
}

onMounted(() => {
  if (allowedMinimized.value) {
    TUICallKitServer.enableFloatWindow(allowedMinimized.value)
  }
  TUICallKitServer.setVideoDisplayMode(videoDisplayMode.value as any)
  TUICallKitServer.setVideoResolution(videoResolution.value as any)
  TUIStore.watch(StoreName.CALL, watchOptions, {
    notifyRangeWhenWatch: NAME.MYSELF
  })
  TUIStore.watch(StoreName.CALL, {
    [NAME.IS_MINIMIZED]: handleIsMinimizedChange
  })
})

function showToast(value: string, type: string) {
  switch (type) {
    case 'info':
      Toast?.info(value as any)
      break
    case 'error':
      Toast?.error(value as any)
      break
    default:
      break
  }
}

onUnmounted(() => {
  TUIStore.unwatch(StoreName.CALL, {
    ...watchOptions,
    [NAME.IS_MINIMIZED]: handleIsMinimizedChange
  })
})

provide(CallInfoContextKey, callInfoContextValue)
provide(CallerUserInfoContextKey, callerUserInfoValue)
provide(UserInfoExcludeVolumeContextKey, userInfoExcludeVolumeContextValue)
provide(FloatWindowContextKey, floatWindowContextValue)
</script>

<style lang="scss">
.TUICallKit-mobile {
  width: 100%;
  height: 100%;

  .singCall {
    width: 100%;
    height: 100%;
  }
}

.transition-animation {
  transform: translateY(-100%);
  animation: slideInDown 0.5s ease forwards;
}

@keyframes slideInDown {
  from {
    transform: translateY(-100%);
  }
  to {
    transform: translateY(0);
  }
}

.TUICallKit-desktop {
  margin: 0 auto;
  position: relative;
  position: relative;
  border-radius: inherit;
  width: 100%;
  height: 100%;
  color: white;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  z-index: 12;
  border-radius: 16px;

  .singCall {
    width: 100%;
    height: 100%;
  }
}

.mobile-audio {
  background-color: white;
}

.miniMized {
  width: 168px !important;
  height: 56px !important;
  overflow: visible !important;
}

.miniMized-mobile-audio {
  width: 72px;
  height: 72px;
  position: fixed;
  top: 40px;
  right: 40px;
}

.miniMized-mobile-video {
  width: 40%;
  height: 30%;
  position: fixed;
  top: 40px;
  right: 40px;
}
</style>
